package com.glodon.paas.registry.demo.consumer;

import org.jboss.netty.channel.*;
import org.jboss.netty.handler.ssl.SslHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.SecretKey;
import javax.net.ssl.SSLSession;
import java.lang.reflect.Method;

/**
 * @author Don Li
 */
public class ServiceConsumerHandler extends SimpleChannelUpstreamHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceConsumerHandler.class);

    @Override
    public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception {
        if (e instanceof ChannelStateEvent) {
            LOGGER.debug(e.toString());
        }
        super.handleUpstream(ctx, e);
    }

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
        final SslHandler handler = ctx.getPipeline().get(SslHandler.class);
        LOGGER.debug("Consumer start ssl handshake");
        ChannelFuture future = handler.handshake();
        future.addListener(new ChannelFutureListener() {
            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                if (future.isSuccess()) {
                    LOGGER.debug("Ssl handshake finished");
                    SSLSession session = handler.getEngine().getSession();
                    LOGGER.debug("Cipher suite: {}", session.getCipherSuite());
                    // get shared secret key via reflection
                    Method method = session.getClass().getDeclaredMethod("getMasterSecret");
                    method.setAccessible(true);
                    if (method.isAccessible()) {
                        SecretKey secretKey = (SecretKey) method.invoke(session);
                        LOGGER.debug("Shared secret key: {}", secretKey);
                    }
                } else {
                    LOGGER.debug("Ssl handshake failed");
                    future.getChannel().close();
                }
            }
        });
    }

    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        LOGGER.info("msg received: {}", e.getMessage());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
        LOGGER.error("Unexpected error", e.getCause());
        e.getChannel().close();
    }
}
